//
//  YCDeviceUtil.m
//  YCRequestModule
//
//  Created by Apple on 2022/11/8.
//

#import "YCDeviceUtil.h"
#import <UIKit/UIKit.h>
#import <AdSupport/AdSupport.h>
#import <SystemConfiguration/CaptiveNetwork.h>
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <CoreTelephony/CTCarrier.h>
#import <ifaddrs.h>
#import <arpa/inet.h>
#import "sys/utsname.h"
#import <OpenUDID/OpenUDID.h>

@implementation YCDeviceUtil

+ (NSString *)ua {
    NSString *userAgent = [NSString stringWithFormat:@"%@/%@ (%@; iOS %@; Scale/%0.2f)", [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleExecutableKey] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleIdentifierKey], [[NSBundle mainBundle] infoDictionary][@"CFBundleShortVersionString"] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleVersionKey], [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion], [[UIScreen mainScreen] scale]];
    return userAgent;
}

+ (NSString *)carrier {
    CTTelephonyNetworkInfo *info = [[CTTelephonyNetworkInfo alloc] init];
    CTCarrier *carrier = [info subscriberCellularProvider];
    NSString *mobileCarrier;
    // 先判断有没有SIM卡，如果没有则不获取本机运营商
    if (!carrier.isoCountryCode) {
        mobileCarrier = @"无运营商";
    } else{
        mobileCarrier = [carrier carrierName];
    }
    return mobileCarrier;
}

+ (YCCarrierType)carrierType {
    YCCarrierType type = YCCarrierTypeUnknow;
    CTTelephonyNetworkInfo *info = [[CTTelephonyNetworkInfo alloc] init];
    CTCarrier *carrier = [info subscriberCellularProvider];
    if (carrier.isoCountryCode) {
        if ([carrier.mobileCountryCode isEqualToString:@"460"]) {   // 460为中国code
            NSString *mobileNetWorkCode = [carrier mobileNetworkCode];
            if ([mobileNetWorkCode isEqualToString:@"00"] ||
                [mobileNetWorkCode isEqualToString:@"02"] ||
                [mobileNetWorkCode isEqualToString:@"07"] ||
                [mobileNetWorkCode isEqualToString:@"08"]) {
                return YCCarrierTypeChinaMobile;  // 中国移动
            } else if ([mobileNetWorkCode isEqualToString:@"01"] ||
                       [mobileNetWorkCode isEqualToString:@"06"] ||
                       [mobileNetWorkCode isEqualToString:@"09"]) {
                return YCCarrierTypeChinaUnicom;  // 中国联通
            } else if ([mobileNetWorkCode isEqualToString:@"03"] ||
                       [mobileNetWorkCode isEqualToString:@"05"] ||
                       [mobileNetWorkCode isEqualToString:@"11"]) {
                return YCCarrierTypeChinaTelecom;  // 中国电信
            }
        } else {
            type = YCCarrierTypeOther;
        }
    }
    return type;
}

+ (YCDeviceNetType)netType {
    YCDeviceNetType netType = YCDeviceNetTypeUnknown;/*
    AFNetworkReachabilityManager *reachabilityManager = [AFNetworkReachabilityManager sharedManager];
    if (reachabilityManager.isReachableViaWiFi) {
        netType = YICDeviceNetTypeWiFi;
    } else if (reachabilityManager.isReachableViaWWAN) {
        netType = YICDeviceNetTypeWWAN;
        NSArray *typeStrings2G = @[CTRadioAccessTechnologyEdge,
                                   CTRadioAccessTechnologyGPRS,
                                   CTRadioAccessTechnologyCDMA1x];
        NSArray *typeStrings3G = @[CTRadioAccessTechnologyHSDPA,
                                   CTRadioAccessTechnologyWCDMA,
                                   CTRadioAccessTechnologyHSUPA,
                                   CTRadioAccessTechnologyCDMAEVDORev0,
                                   CTRadioAccessTechnologyCDMAEVDORevA,
                                   CTRadioAccessTechnologyCDMAEVDORevB,
                                   CTRadioAccessTechnologyeHRPD];
        NSArray *typeStrings4G = @[CTRadioAccessTechnologyLTE];
        
        CTTelephonyNetworkInfo *teleInfo= [[CTTelephonyNetworkInfo alloc] init];
        NSString *accessString = teleInfo.currentRadioAccessTechnology;
        if ([typeStrings4G containsObject:accessString]) {
            netType = YICDeviceNetType4G;
        } else if ([typeStrings3G containsObject:accessString]) {
            netType = YICDeviceNetType3G;
        } else if ([typeStrings2G containsObject:accessString]) {
            netType = YICDeviceNetType2G;
        }
    }*/
    return netType;
}

+ (YCDeviceOrientation)orientation {
    UIDeviceOrientation ori = [[UIDevice currentDevice] orientation];
    if (ori == UIDeviceOrientationPortrait || ori == UIDeviceOrientationPortraitUpsideDown) {
        return YCDeviceOrientationPortrait;
    } else if (ori == UIDeviceOrientationLandscapeLeft || ori == UIDeviceOrientationLandscapeRight) {
        return YCDeviceOrientationLandscape;
    } else {
        return YCDeviceOrientationUnknow;
    }
}

+ (NSString *)osVersion {
    NSOperatingSystemVersion sysVer = [[NSProcessInfo processInfo] operatingSystemVersion];
    return [NSString stringWithFormat:@"%ld.%ld.%ld", (long)sysVer.majorVersion, (long)sysVer.minorVersion, (long)sysVer.patchVersion];
}

+ (NSString *)idfa {
    return [[ASIdentifierManager sharedManager].advertisingIdentifier UUIDString];
}

+ (NSString *)uuid {
    CFUUIDRef uniqueID = CFUUIDCreate(kCFAllocatorDefault);
    CFStringRef idString = CFUUIDCreateString(kCFAllocatorDefault, uniqueID);
    NSString *uuId = [((__bridge NSString *)idString) copy];
    CFRelease(uniqueID);
    CFRelease(idString);
    return uuId;
}

+ (NSString *)openudid {
    NSString *openudid = [OpenUDID value];
    return openudid.length > 0 ? openudid : @"";
}

+ (NSString *)ipAddress {
    NSString *address = @"127.0.0.1";     // 本地ip(lo0)
    struct ifaddrs *interfaces = NULL;
    struct ifaddrs *temp_addr = NULL;
    int success = 0;
    // retrieve the current interfaces - returns 0 on success
    success = getifaddrs(&interfaces);
    if (success == 0) {
        // Loop through linked list of interfaces
        temp_addr = interfaces;
        while(temp_addr != NULL) {
            if(temp_addr->ifa_addr->sa_family == AF_INET) {
                // Check if interface is en0 which is the wifi connection on the iPhone
                // pdp_ip0 is the wwan and bridge0 is the hotspot
                if ([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"] ||
                    [[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"pdp_ip0"] ||
                    [[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"bridge0"]) {
                    // Get NSString from C String
                    address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
                    break;
                }
            }
            temp_addr = temp_addr->ifa_next;
        }
    }
    // Free memory
    freeifaddrs(interfaces);
    return address ;
}

+ (NSString *)macAddress {
    NSArray *ifs = (__bridge_transfer NSArray *)CNCopySupportedInterfaces();
    if (!ifs) {
        return @"";
    }
    NSDictionary *info = nil;
    for (NSString *ifnam in ifs) {
        info = (__bridge_transfer NSDictionary *)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);
        if (info && [info count]) { break; }
    }
    // BSSID = "a4:2b:8c:c:7f:bd";
    NSString *bssid = [info objectForKey:@"BSSID"];
    return bssid ? bssid : @"";
}

+ (NSString *)model {
    struct utsname systemInfo;
    uname(&systemInfo);
    NSString *deviceString = [NSString stringWithCString:systemInfo.machine
                                                encoding:NSUTF8StringEncoding];
    // iPhone
    if ([deviceString isEqualToString:@"iPhone1,1"])    return @"iPhone 1G";
    if ([deviceString isEqualToString:@"iPhone1,2"])    return @"iPhone 3G";
    
    if ([deviceString isEqualToString:@"iPhone2,1"])    return @"iPhone 3GS";
    
    if ([deviceString isEqualToString:@"iPhone3,1"])    return @"iPhone 4";
    if ([deviceString isEqualToString:@"iPhone3,2"])    return @"Verizon iPhone 4";
    
    if ([deviceString isEqualToString:@"iPhone4,1"])    return @"iPhone 4S";
    
    if ([deviceString isEqualToString:@"iPhone5,1"])    return @"iPhone 5";
    if ([deviceString isEqualToString:@"iPhone5,2"])    return @"iPhone 5";
    if ([deviceString isEqualToString:@"iPhone5,3"])    return @"iPhone 5C";
    if ([deviceString isEqualToString:@"iPhone5,4"])    return @"iPhone 5C";
    
    if ([deviceString isEqualToString:@"iPhone6,1"])    return @"iPhone 5S";
    if ([deviceString isEqualToString:@"iPhone6,2"])    return @"iPhone 5S";
    
    if ([deviceString isEqualToString:@"iPhone7,1"])    return @"iPhone 6 Plus";
    if ([deviceString isEqualToString:@"iPhone7,2"])    return @"iPhone 6";
    
    if ([deviceString isEqualToString:@"iPhone8,1"])    return @"iPhone 6s";
    if ([deviceString isEqualToString:@"iPhone8,2"])    return @"iPhone 6s Plus";
    if ([deviceString isEqualToString:@"iPhone8,4"])    return @"iPhone SE";
    
    if ([deviceString isEqualToString:@"iPhone9,1"])    return @"iPhone 7";
    if ([deviceString isEqualToString:@"iPhone9,3"])    return @"iPhone 7";
    if ([deviceString isEqualToString:@"iPhone9,2"])    return @"iPhone 7 Plus";
    if ([deviceString isEqualToString:@"iPhone9,4"])    return @"iPhone 7 Plus";
    
    if ([deviceString isEqualToString:@"iPhone10,1"])    return @"iPhone 8";
    if ([deviceString isEqualToString:@"iPhone10,4"])    return @"iPhone 8";
    if ([deviceString isEqualToString:@"iPhone10,2"])    return @"iPhone 8 Plus";
    if ([deviceString isEqualToString:@"iPhone10,5"])    return @"iPhone 8 Plus";
    if ([deviceString isEqualToString:@"iPhone10,3"])    return @"iPhone X";
    if ([deviceString isEqualToString:@"iPhone10,6"])    return @"iPhone X";
    
    if ([deviceString isEqualToString:@"iPhone11,8"])    return @"iPhone XR";
    if ([deviceString isEqualToString:@"iPhone11,2"])    return @"iPhone XS";
    if ([deviceString isEqualToString:@"iPhone11,4"])    return @"iPhone XS MAX";
    if ([deviceString isEqualToString:@"iPhone11,6"])    return @"iPhone XS MAX";
    
    if ([deviceString isEqualToString:@"iPhone12,1"])    return @"iPhone_11";
    if ([deviceString isEqualToString:@"iPhone12,3"])    return @"iPhone_11_Pro";
    if ([deviceString isEqualToString:@"iPhone12,5"])    return @"iPhone_11_Pro_Max";
    if ([deviceString isEqualToString:@"iPhone12,8"])    return @"iPhone SE 2nd";
    
    if ([deviceString isEqualToString:@"iPhone13,1"])    return @"iPhone 12 mini";
    if ([deviceString isEqualToString:@"iPhone13,2"])    return @"iPhone 12";
    if ([deviceString isEqualToString:@"iPhone13,3"])    return @"iPhone 12 Pro";
    if ([deviceString isEqualToString:@"iPhone13,4"])    return @"iPhone 12 Pro Max";
    
    if ([deviceString isEqualToString:@"iPhone14,4"])    return @"iPhone 13 mini";
    if ([deviceString isEqualToString:@"iPhone14,5"])    return @"iPhone 13";
    if ([deviceString isEqualToString:@"iPhone14,2"])    return @"iPhone 13 Pro";
    if ([deviceString isEqualToString:@"iPhone14,3"])    return @"iPhone 13 Pro Max";
    if ([deviceString isEqualToString:@"iPhone14,6"])    return @"iPhone SE 3nd";
    if ([deviceString isEqualToString:@"iPhone14,7"])    return @"iPhone 14";
    if ([deviceString isEqualToString:@"iPhone14,8"])    return @"iPhone 14 Plus";
    
    if ([deviceString isEqualToString:@"iPhone15,2"])    return @"iPhone 14 Pro";
    if ([deviceString isEqualToString:@"iPhone15,3"])    return @"iPhone 14 Pro Max";
    if ([deviceString isEqualToString:@"iPhone15,4"])    return @"iPhone 15";
    if ([deviceString isEqualToString:@"iPhone15,5"])    return @"iPhone 15 Plus";

    if ([deviceString isEqualToString:@"iPhone16,1"])    return @"iPhone 15 Pro";
    if ([deviceString isEqualToString:@"iPhone16,2"])    return @"iPhone 15 Pro Max";
    
    if ([deviceString isEqualToString:@"iPhone17,1"])    return @"iPhone 16 Pro";
    if ([deviceString isEqualToString:@"iPhone17,2"])    return @"iPhone 16 Pro Max";
    if ([deviceString isEqualToString:@"iPhone17,3"])    return @"iPhone 16";
    if ([deviceString isEqualToString:@"iPhone17,4"])    return @"iPhone 16 Plus";

    
    // iPod
    if ([deviceString isEqualToString:@"iPod1,1"])      return @"iPod Touch 1G";
    if ([deviceString isEqualToString:@"iPod2,1"])      return @"iPod Touch 2G";
    if ([deviceString isEqualToString:@"iPod3,1"])      return @"iPod Touch 3G";
    if ([deviceString isEqualToString:@"iPod4,1"])      return @"iPod Touch 4G";
    if ([deviceString isEqualToString:@"iPod5,1"])      return @"iPod Touch 5G";
    if ([deviceString isEqualToString:@"iPod7,1"])      return @"iPod Touch 6G";
    // iPad
    if ([deviceString isEqualToString:@"iPad1,1"])      return @"iPad";
    if ([deviceString isEqualToString:@"iPad2,1"])      return @"iPad 2 (WiFi)";
    if ([deviceString isEqualToString:@"iPad2,2"])      return @"iPad 2 (GSM)";
    if ([deviceString isEqualToString:@"iPad2,3"])      return @"iPad 2 (CDMA)";
    if ([deviceString isEqualToString:@"iPad2,4"])      return @"iPad 2 (32nm)";
    if ([deviceString isEqualToString:@"iPad2,5"])      return @"iPad mini (WiFi)";
    if ([deviceString isEqualToString:@"iPad2,6"])      return @"iPad mini (GSM)";
    if ([deviceString isEqualToString:@"iPad2,7"])      return @"iPad mini (CDMA)";
    if ([deviceString isEqualToString:@"iPad3,1"])      return @"iPad 3(WiFi)";
    if ([deviceString isEqualToString:@"iPad3,2"])      return @"iPad 3(CDMA)";
    if ([deviceString isEqualToString:@"iPad3,3"])      return @"iPad 3(4G)";
    if ([deviceString isEqualToString:@"iPad3,4"])      return @"iPad 4 (WiFi)";
    if ([deviceString isEqualToString:@"iPad3,5"])      return @"iPad 4 (4G)";
    if ([deviceString isEqualToString:@"iPad3,6"])      return @"iPad 4 (CDMA)";
    if ([deviceString isEqualToString:@"iPad4,1"])      return @"iPad Air";
    if ([deviceString isEqualToString:@"iPad4,2"])      return @"iPad Air";
    if ([deviceString isEqualToString:@"iPad4,3"])      return @"iPad Air";
    if ([deviceString isEqualToString:@"iPad4,4"] ||
        [deviceString isEqualToString:@"iPad4,5"] ||
        [deviceString isEqualToString:@"iPad4,6"]) {
        return @"iPad mini 2";
    }
    if ([deviceString isEqualToString:@"iPad4,7"] ||
        [deviceString isEqualToString:@"iPad4,8"] ||
        [deviceString isEqualToString:@"iPad4,9"]) {
        return @"iPad mini 3";
    }
    if ([deviceString isEqualToString:@"iPad5,1"])      return @"iPad mini 4";
    if ([deviceString isEqualToString:@"iPad5,2"])      return @"iPad mini 4";
    if ([deviceString isEqualToString:@"iPad5,3"])      return @"iPad Air 2";
    if ([deviceString isEqualToString:@"iPad5,4"])      return @"iPad Air 2";
    if ([deviceString isEqualToString:@"iPad6,3"])      return @"iPad Pro (9.7-inch)";
    if ([deviceString isEqualToString:@"iPad6,4"])      return @"iPad Pro (9.7-inch)";
    if ([deviceString isEqualToString:@"iPad6,7"])      return @"iPad Pro 1 (12.9-inch)";
    if ([deviceString isEqualToString:@"iPad6,8"])      return @"iPad Pro 1 (12.9-inch)";
    if ([deviceString isEqualToString:@"iPad6,11"])      return @"iPad (2017)";
    if ([deviceString isEqualToString:@"iPad6,12"])      return @"iPad (2017)";
    if ([deviceString isEqualToString:@"iPad7,1"])      return @"iPad Pro 2 (12.9-inch)";
    if ([deviceString isEqualToString:@"iPad7,2"])      return @"iPad Pro 2 (12.9-inch)";
    if ([deviceString isEqualToString:@"iPad7,3"])      return @"iPad Pro (10.5-inch)";
    if ([deviceString isEqualToString:@"iPad7,4"])      return @"iPad Pro (10.5-inch)";
    if ([deviceString isEqualToString:@"iPad7,6"] || 
        [deviceString isEqualToString:@"iPad7,5"]) {
        return @"iPad (6th generation)";
    }
    
    if ([deviceString isEqualToString:@"iPad7,11"] ||
        [deviceString isEqualToString:@"iPad7,12"]) {
        return @"iPad (7th generation)";
    }
    
    if ([deviceString isEqualToString:@"iPad8,1"] ||
        [deviceString isEqualToString:@"iPad8,2"] ||
        [deviceString isEqualToString:@"iPad8,3"] ||
        [deviceString isEqualToString:@"iPad8,4"]
        ) {
        return @"iPad Pro (11-inch)";
    }
    
    if ([deviceString isEqualToString:@"iPad8,5"] ||
        [deviceString isEqualToString:@"iPad8,6"] ||
        [deviceString isEqualToString:@"iPad8,7"] ||
        [deviceString isEqualToString:@"iPad8,8"]
        ) {
        return @"iPad Pro (12.9-inch) (3rd generation)";
    }
    
    if ([deviceString isEqualToString:@"iPad8,9"] ||
        [deviceString isEqualToString:@"iPad8,10"]
        ) {
        return @"iPad Pro (11-inch) (2nd generation)";
    }
    
    if ([deviceString isEqualToString:@"iPad8,11"] ||
        [deviceString isEqualToString:@"iPad8,12"]
        ) {
        return @"iPad Pro (12.9-inch) (4th generation)";
    }
    
    if ([deviceString isEqualToString:@"iPad8,11"] ||
        [deviceString isEqualToString:@"iPad8,12"]
        ) {
        return @"iPad Pro (12.9-inch) (4th generation)";
    }
    
    if ([deviceString isEqualToString:@"iPad11,1"] ||
        [deviceString isEqualToString:@"iPad11,2"]
        ) {
        return @"iPad mini (5th generation)";
    }
    
    if ([deviceString isEqualToString:@"iPad11,3"] ||
        [deviceString isEqualToString:@"iPad11,4"]
        ) {
        return @"iPad Air (3rd generation)";
    }
    
    if ([deviceString isEqualToString:@"iPad11,6"] ||
        [deviceString isEqualToString:@"iPad11,7"]
        ) {
        return @"iPad (8th generation)";
    }
    
    if ([deviceString isEqualToString:@"iPad12,1"] ||
        [deviceString isEqualToString:@"iPad12,2"]
        ) {
        return @"iPad (9th generation)";
    }
    
    if ([deviceString isEqualToString:@"iPad13,1"] ||
        [deviceString isEqualToString:@"iPad13,2"]
        ) {
        return @"iPad Air (4th generation)";
    }
    
    if ([deviceString isEqualToString:@"iPad13,4"] ||
        [deviceString isEqualToString:@"iPad13,5"] ||
        [deviceString isEqualToString:@"iPad13,6"] ||
        [deviceString isEqualToString:@"iPad13,7"]
        ) {
        return @"iPad Pro (11-inch) (3rd generation)";
    }
    
    if ([deviceString isEqualToString:@"iPad13,8"] ||
        [deviceString isEqualToString:@"iPad13,9"] ||
        [deviceString isEqualToString:@"iPad13,10"] ||
        [deviceString isEqualToString:@"iPad13,11"]
        ) {
        return @"iPad Pro (12.9-inch) (5th generation)";
    }
    
    if ([deviceString isEqualToString:@"iPad13,16"] ||
        [deviceString isEqualToString:@"iPad13,17"]
        ) {
        return @"iPad Air (5th generation)";
    }
    
    if ([deviceString isEqualToString:@"iPad14,1"] ||
        [deviceString isEqualToString:@"iPad14,2"]
        ) {
        return @"iPad mini (6th generation)";
    }
    
    if ([deviceString isEqualToString:@"iPad14,8"] ||
        [deviceString isEqualToString:@"iPad14,9"]
        ) {
        return @"iPad Air 11-inch (M2)";
    }
    
    if ([deviceString isEqualToString:@"iPad14,10"] ||
        [deviceString isEqualToString:@"iPad14,11"]
        ) {
        return @"iPad Air 13-inch (M2)";
    }
    
    if ([deviceString isEqualToString:@"iPad16,1"] ||
        [deviceString isEqualToString:@"iPad16,2"]
        ) {
        return @"iPad mini (A17 Pro)";
    }
    
    if ([deviceString isEqualToString:@"iPad16,3"] ||
        [deviceString isEqualToString:@"iPad16,4"]
        ) {
        return @"iPad Pro 11-inch (M4)";
    }
    
    if ([deviceString isEqualToString:@"iPad16,5"] ||
        [deviceString isEqualToString:@"iPad16,6"]
        ) {
        return @"iPad Pro 13-inch (M4)";
    }

    if ([deviceString containsString:@"iPad"]) {
        return @"iPad";
    }
    
    if ([deviceString containsString:@"iPod"]) {
        return @"iPod";
    }
    
    // Simulator
    if ([deviceString isEqualToString:@"i386"])         return @"Simulator";
    if ([deviceString isEqualToString:@"x86_64"])       return @"Simulator";
    
    return deviceString;
}

+ (NSInteger)ppi {
    NSInteger devicePPI = 0;
    return devicePPI;
}

+ (NSString *)vendor {
    return @"Apple";
}

+ (NSString *)brand {
    return @"Apple";
}

+ (NSString *)appVersion {
    return [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
}

+ (NSString *)systemVersion {
    return [[UIDevice currentDevice] systemVersion];
}

@end
